﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Farigola.Engine.SystemData.Entity.Type;
using Farigola.Engine.SystemData.Entity.inst;
using Farigola.Engine.SystemData.DataValue;

namespace Farigola.Engine.TestUnit
{
    [TestFixture]
    public class EntityStructListTestUnit
	{
        [Test]
        public void findTypeStructListByName()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");

            // get the tool to find entities in the project
            EntityFinder entFinder = prj.GetEntityFinder();

            EntTypeBase typeBaseStructList = entFinder.FindEntTypeBaseByName("list");
            Assert.IsNotNull(typeBaseStructList, "The type 'list' should be found by the name.");

            // convert to a type struct list to check it
            Assert.IsTrue((typeBaseStructList is EntTypeStructList), "The ent type should be 'list'.");
        }

        // items are ent inst.
        [Test]
        public void CreateListofDataValueStringCheckNameAndTypeItem()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");


            // create an inst list of string, under the root user by default
            EntInstStructList instListString = prj.CreateEntInstStructList("string", "MyListString");
            Assert.IsNotNull(instListString, "The inst list 'MyListString' should exists.");

            // check the name 
            Assert.AreEqual("MyListString", instListString.GetName(), "The name of the inst list should be 'MyListString'.");

            // check the type of items: DataValueString
            Assert.IsNull(instListString.EntTypeBaseItems, "The type of items should not be entity instance string.");
            Assert.IsFalse(instListString.IsEntTypeBaseItems, "The type of items should not be entity instance string.");
 
            Assert.IsNotNull(instListString.DataValueTypeItems, "The type of items should be data value string.");
            Assert.IsTrue(instListString.IsDataValueTypeItems, "The type of items should be data value string.");
        }

        [Test]
        public void CreateListNameNull()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");


            // create an inst list of string, under the root user by default
            EntInstStructList instListString = prj.CreateEntInstStructList("string", null);
            Assert.IsNull(instListString, "The name of the list is null.");
        }

        [Test]
        public void CreateListNameEmpty()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");


            // create an inst list of string, under the root user by default
            EntInstStructList instListString = prj.CreateEntInstStructList("string", "");
            Assert.IsNull(instListString, "The name of the list is empty.");
        }

        [Test]
        public void CreateListNameBlank()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");


            // create an inst list of string, under the root user by default
            EntInstStructList instListString = prj.CreateEntInstStructList("string", "  ");
            Assert.IsNull(instListString, "The name of the list is blank.");
        }

        [Test]
        public void CreateListNameStringIsReserved()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");


            // create an inst list of string, under the root user by default
            EntInstStructList instListString = prj.CreateEntInstStructList("string", "string");
            Assert.IsNull(instListString, "The name of the list 'string', can't be used, if reserved.");
        }

        [Test]
        public void CreateListNameListIsReserved()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");


            // create an inst list of string, under the root user by default
            EntInstStructList instListString = prj.CreateEntInstStructList("string", "list");
            Assert.IsNull(instListString, "The name of the list 'list', can't be used, if reserved.");
        }

        // items are ent inst.
        [Test]
        public void CreateListofStringFindAndCheck()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");

            // create an inst list of string, under the root user by default
            EntInstStructList instListString = prj.CreateEntInstStructList("string", "MyListString");

            // get the tool to find entities in the project
            EntityFinder entFinder = prj.GetEntityFinder();

            // find the inst list, by the name, scan recursilvy
            EntInstStructList instListStringFind = entFinder.FindEntInstStructListByName("MyListString");
            Assert.IsNotNull(instListStringFind, "The inst list 'MyListString' should be found.");

            // check the name
            Assert.AreEqual("MyListString", instListStringFind.GetName(), "The name of the inst list should be 'MyListString'.");

            // check the type of items: DataValueString
            Assert.IsNull(instListString.EntTypeBaseItems, "The type of items should not be entity instance string.");
            Assert.IsFalse(instListString.IsEntTypeBaseItems, "The type of items should not be entity instance string.");

            Assert.IsNotNull(instListString.DataValueTypeItems, "The type of items should be data value string.");
            Assert.IsTrue(instListString.IsDataValueTypeItems, "The type of items should be data value string.");
        }


        // try create a list with a wrong name
        [Test]
        public void CreateListofStringWrongName()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");

            // create an inst list of string (dataValue by default), under the root user by default
            EntInstStructList instList = prj.CreateEntInstStructList("string", "  ");
            Assert.IsNull(instList, "The inst list should not be created, the name is wrong.");
        }

        // try create a list with a wrong type
        [Test]
        public void CreateListofStringWrongType()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");

            // create an inst list of string, under the root user by default
            EntInstStructList instList = prj.CreateEntInstStructList("XSDSFS", "l");
            Assert.IsNull(instList, "The inst list should not be created, the type is wrong.");
        }

        // try create a list with a wrong type
        [Test]
        public void CreateListofStringAddItem()
        {
            Engine engine = EngineCommonTestUnit.CreateInitEngine();
            Workspace wksp = engine.GetWorkspace();

            // create a project
            Project prj = wksp.CreateActiveProject("prj");

            // create an inst list of string (data value by default), under the root user by default
            EntInstStructList instList = prj.CreateEntInstStructList("string", "MyList");

            // create a data value string
            DataValueString dataValueString = prj.CreateDataValueString("bonjour");

            // add en inst item to the list
            bool res= prj.AddItemToList(instList, dataValueString);
            Assert.IsTrue(res, "The item dataValueString should be added to the list.");

            // check the size of the list, contains one item
            Assert.AreEqual(1, instList.Count, "The list should have one item.");

            // try add a data value int, by not possible
            DataValueInt dataValueInt = prj.CreateDataValueInt(12);
            res = prj.AddItemToList(instList, dataValueInt);
            Assert.IsFalse(res, "The item dataValueInt should be added to the list.");

            // check the size of the list, contains one item
            Assert.AreEqual(1, instList.Count, "The list should have yet one item.");
        }


        // try create a list with a wrong type: not implemented (class)


        // create 2 list with same name; error

        // create list of strings and add items

        // create list of strings, add items and then remove one and all

        // create a list of entity string, add one and more items


        // create a list of a type class
        // possible today?

        // create a list generic (type generic)
        // possible today?
    }
}
